package com.replication.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import com.replication.logging.Logger;

public class Driver implements java.sql.Driver{
    private static Logger logger = Logger.getLogger(Driver.class);
    static{
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException e) {
            throw new RuntimeException("Can't register driver:" + Driver.class);
        }
        
        initDriver("com.mysql.jdbc.Driver");
        initDriver("oracle.jdbc.driver.OracleDriver");
        initDriver("com.ibm.db2.jdbc.app.DB2Driver");
        initDriver("com.microsoft.jdbc.sqlserver.SQLServerDriver");
        initDriver("com.sybase.jdbc.SybDriver");
        initDriver("com.informix.jdbc.IfxDriver");
        initDriver("org.postgresql.Driver");
        initDriver("net.sourceforge.jtds.jdbc.Driver");
    }
    
    private static void initDriver(String driverName){
    	try {
            Class.forName(driverName);
            logger.info("{successfully register driver} : " + driverName);
        } catch (ClassNotFoundException e) {
 
        }
    }

    @Override
    public boolean acceptsURL(String url) throws SQLException {
        if(url.startsWith(URLPrefix.URL_PREFIX)){
            return true;
        }
        return false;
    }

    @Override
    public Connection connect(String url, Properties info) throws SQLException {
    	
    	logger.info("url:"+url);
    	logger.info("Properties:"+info.entrySet());
    	if(!acceptsURL(url)){
    		throw new SQLException("Not support URL:" + url);
    	}
        URLParser parser = new URLParser(url);
        String masterUrl = parser.getMasterUrl();
        
        List<Connection> slavConns = new ArrayList<Connection>();
        Connection mastConn = DriverManager.getConnection(masterUrl, info);
        
        for(String slavRrl: parser.getSlaverUrl()){
            Connection slavConn = DriverManager.getConnection(slavRrl, info);
            slavConns.add(slavConn);
        }
        
        ConnectionSelector selector = makeConnectionSelector(masterUrl);
        logger.debug("{connection selector} " + selector.getClass().getName());
        return new ReplicationConnectionProxy(mastConn,slavConns,selector);
    }

    @Override
    public int getMajorVersion() {
        return 1;
    }

    @Override
    public int getMinorVersion() {
        return 1;
    }

    @Override
    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
        URLParser parser = new URLParser(url);
        return DriverManager.getDriver(parser.getMasterUrl()).getPropertyInfo(url, info);
    }

    @Override
    public boolean jdbcCompliant() {
        return true;
    }
    
    private ConnectionSelector makeConnectionSelector(String url){
        if(url.startsWith("jdbc:mysql:")){
            return new MysqlConnectionSelector();
        }
        
        return new DefaultConnectionSelector();
    }
}
